[hvm/qemu] Flip the device model over to using the new Xen event channels
authorsos22@douglas.cl.cam.ac.uk <sos22@douglas.cl.cam.ac.uk>
Tue, 8 Aug 2006 10:19:29 +0000 (11:19 +0100)
committersos22@douglas.cl.cam.ac.uk <sos22@douglas.cl.cam.ac.uk>
Tue, 8 Aug 2006 10:19:29 +0000 (11:19 +0100)
support.

Signed-off-by: Steven Smith <ssmith@xensource.com>
22 files changed:
tools/ioemu/target-i386-dm/helper2.c
tools/libxc/xc_hvm_build.c
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/intercept.c
xen/arch/x86/hvm/io.c
xen/arch/x86/hvm/platform.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/svm/vmcb.c
xen/arch/x86/hvm/svm/x86_32/exits.S
xen/arch/x86/hvm/svm/x86_64/exits.S
xen/arch/x86/hvm/vlapic.c
xen/arch/x86/hvm/vmx/io.c
xen/arch/x86/hvm/vmx/vmcs.c
xen/arch/x86/hvm/vmx/vmx.c
xen/arch/x86/hvm/vmx/x86_32/exits.S
xen/arch/x86/hvm/vmx/x86_64/exits.S
xen/include/asm-x86/hvm/hvm.h
xen/include/asm-x86/hvm/io.h
xen/include/asm-x86/hvm/support.h
xen/include/asm-x86/hvm/vcpu.h
xen/include/public/hvm/ioreq.h
xen/include/xen/event.h

index ffa24ac190797a20e28fa2359b0d945970ae72ed..4f1a33c7e7405236102a0208ebc6f38e225c7c01 100644 (file)
@@ -82,6 +82,10 @@ int xce_handle = -1;
 /* which vcpu we are serving */
 int send_vcpu = 0;
 
+//the evtchn port for polling the notification,
+#define NR_CPUS 32
+evtchn_port_t ioreq_local_port[NR_CPUS];
+
 CPUX86State *cpu_x86_init(void)
 {
     CPUX86State *env;
@@ -113,7 +117,7 @@ CPUX86State *cpu_x86_init(void)
                 fprintf(logfile, "bind interdomain ioctl error %d\n", errno);
                 return NULL;
             }
-            shared_page->vcpu_iodata[i].dm_eport = rc;
+            ioreq_local_port[i] = rc;
         }
     }
 
@@ -184,8 +188,7 @@ void sp_info()
 
     for (i = 0; i < vcpus; i++) {
         req = &(shared_page->vcpu_iodata[i].vp_ioreq);
-        term_printf("vcpu %d: event port %d\n", i,
-                    shared_page->vcpu_iodata[i].vp_eport);
+        term_printf("vcpu %d: event port %d\n", i, ioreq_local_port[i]);
         term_printf("  req state: %x, pvalid: %x, addr: %"PRIx64", "
                     "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
                     req->state, req->pdata_valid, req->addr,
@@ -204,6 +207,7 @@ static ioreq_t *__cpu_get_ioreq(int vcpu)
 
     if (req->state == STATE_IOREQ_READY) {
         req->state = STATE_IOREQ_INPROCESS;
+        rmb();
         return req;
     }
 
@@ -226,7 +230,7 @@ static ioreq_t *cpu_get_ioreq(void)
     port = xc_evtchn_pending(xce_handle);
     if (port != -1) {
         for ( i = 0; i < vcpus; i++ )
-            if ( shared_page->vcpu_iodata[i].dm_eport == port )
+            if ( ioreq_local_port[i] == port )
                 break;
 
         if ( i == vcpus ) {
@@ -447,8 +451,10 @@ void cpu_handle_ioreq(void *opaque)
         }
 
         /* No state change if state = STATE_IORESP_HOOK */
-        if (req->state == STATE_IOREQ_INPROCESS)
+        if (req->state == STATE_IOREQ_INPROCESS) {
+            mb();
             req->state = STATE_IORESP_READY;
+        }
         env->send_event = 1;
     }
 }
@@ -479,8 +485,7 @@ int main_loop(void)
 
         if (env->send_event) {
             env->send_event = 0;
-            xc_evtchn_notify(xce_handle,
-                             shared_page->vcpu_iodata[send_vcpu].dm_eport);
+            xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
         }
     }
     destroy_hvm_domain();
index bdfb1cf976b9b2d0b4613ddf4b5dac1968086449..19138ff968aab96a5936bd7460407000d7f4c62f 100644 (file)
@@ -294,26 +294,13 @@ static int setup_guest(int xc_handle,
         shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
     munmap(shared_info, PAGE_SIZE);
 
-    /* Populate the event channel port in the shared page */
+    /* Paranoia */
     shared_page_frame = page_array[(v_end >> PAGE_SHIFT) - 1];
     if ( (sp = (shared_iopage_t *) xc_map_foreign_range(
               xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
               shared_page_frame)) == 0 )
         goto error_out;
     memset(sp, 0, PAGE_SIZE);
-
-    /* FIXME: how about if we overflow the page here? */
-    for ( i = 0; i < vcpus; i++ ) {
-        unsigned int vp_eport;
-
-        vp_eport = xc_evtchn_alloc_unbound(xc_handle, dom, 0);
-        if ( vp_eport < 0 ) {
-            PERROR("Couldn't get unbound port from VMX guest.\n");
-            goto error_out;
-        }
-        sp->vcpu_iodata[i].vp_eport = vp_eport;
-    }
-
     munmap(sp, PAGE_SIZE);
 
     xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, (v_end >> PAGE_SHIFT) - 2);
index 9c0c3e00d54fc11d5823907af3b4fe578e98506a..72b261e34a24f15c5a873a8571f01e4f75931153 100644 (file)
@@ -29,6 +29,7 @@
 #include <xen/domain_page.h>
 #include <xen/hypercall.h>
 #include <xen/guest_access.h>
+#include <xen/event.h>
 #include <asm/current.h>
 #include <asm/io.h>
 #include <asm/shadow.h>
@@ -160,6 +161,29 @@ void hvm_map_io_shared_page(struct vcpu *v)
     d->arch.hvm_domain.shared_page_va = (unsigned long)p;
 }
 
+void hvm_create_event_channels(struct vcpu *v)
+{
+    vcpu_iodata_t *p;
+    struct vcpu *o;
+
+    if ( v->vcpu_id == 0 ) {
+        /* Ugly: create event channels for every vcpu when vcpu 0
+           starts, so that they're available for ioemu to bind to. */
+        for_each_vcpu(v->domain, o) {
+            p = get_vio(v->domain, o->vcpu_id);
+            o->arch.hvm_vcpu.xen_port = p->vp_eport =
+                alloc_unbound_xen_event_channel(o, 0);
+            DPRINTK("Allocated port %d for hvm.\n", o->arch.hvm_vcpu.xen_port);
+        }
+    }
+}
+
+void hvm_release_assist_channel(struct vcpu *v)
+{
+    free_xen_event_channel(v, v->arch.hvm_vcpu.xen_port);
+}
+
+
 void hvm_setup_platform(struct domain* d)
 {
     struct hvm_domain *platform;
index 5c8e57c555ae2a683c99783cb1ec27b5106c4fef..8bc06ada8decf7fb7798d6fac6b0fa3c6bb773a2 100644 (file)
@@ -211,7 +211,7 @@ void hlt_timer_fn(void *data)
 {
     struct vcpu *v = data;
 
-    evtchn_set_pending(v, iopacket_port(v));
+    hvm_prod_vcpu(v);
 }
 
 static __inline__ void missed_ticks(struct periodic_time *pt)
index 6549f8946d053d8f539eef131cc6b9a3f19de209..dec35b2f5566c321440d3e14dab632c52f3987d2 100644 (file)
@@ -687,84 +687,17 @@ void hvm_io_assist(struct vcpu *v)
 
     p = &vio->vp_ioreq;
 
-    /* clear IO wait HVM flag */
-    if ( test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) ) {
-        if ( p->state == STATE_IORESP_READY ) {
-            p->state = STATE_INVALID;
-            clear_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags);
-
-            if ( p->type == IOREQ_TYPE_PIO )
-                hvm_pio_assist(regs, p, io_opp);
-            else
-                hvm_mmio_assist(regs, p, io_opp);
-
-            /* Copy register changes back into current guest state. */
-            hvm_load_cpu_guest_regs(v, regs);
-            memcpy(guest_cpu_user_regs(), regs, HVM_CONTEXT_STACK_BYTES);
-        }
-        /* else an interrupt send event raced us */
-    }
-}
-
-/*
- * On exit from hvm_wait_io, we're guaranteed not to be waiting on
- * I/O response from the device model.
- */
-void hvm_wait_io(void)
-{
-    struct vcpu *v = current;
-    struct domain *d = v->domain;
-    int port = iopacket_port(v);
-
-    for ( ; ; )
-    {
-        /* Clear master flag, selector flag, event flag each in turn. */
-        v->vcpu_info->evtchn_upcall_pending = 0;
-        clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
-        smp_mb__after_clear_bit();
-        if ( test_and_clear_bit(port, &d->shared_info->evtchn_pending[0]) )
-            hvm_io_assist(v);
-
-        /* Need to wait for I/O responses? */
-        if ( !test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
-            break;
-
-        do_sched_op_compat(SCHEDOP_block, 0);
-    }
-
-    /*
-     * Re-set the selector and master flags in case any other notifications
-     * are pending.
-     */
-    if ( d->shared_info->evtchn_pending[port/BITS_PER_LONG] )
-        set_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
-    if ( v->vcpu_info->evtchn_pending_sel )
-        v->vcpu_info->evtchn_upcall_pending = 1;
-}
-
-void hvm_safe_block(void)
-{
-    struct vcpu *v = current;
-    struct domain *d = v->domain;
-    int port = iopacket_port(v);
-
-    for ( ; ; )
-    {
-        /* Clear master flag & selector flag so we will wake from block. */
-        v->vcpu_info->evtchn_upcall_pending = 0;
-        clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
-        smp_mb__after_clear_bit();
-
-        /* Event pending already? */
-        if ( test_bit(port, &d->shared_info->evtchn_pending[0]) )
-            break;
+    if ( p->state == STATE_IORESP_READY ) {
+        p->state = STATE_INVALID;
+        if ( p->type == IOREQ_TYPE_PIO )
+            hvm_pio_assist(regs, p, io_opp);
+        else
+            hvm_mmio_assist(regs, p, io_opp);
 
-        do_sched_op_compat(SCHEDOP_block, 0);
+        /* Copy register changes back into current guest state. */
+        hvm_load_cpu_guest_regs(v, regs);
+        memcpy(guest_cpu_user_regs(), regs, HVM_CONTEXT_STACK_BYTES);
     }
-
-    /* Reflect pending event in selector and master flags. */
-    set_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
-    v->vcpu_info->evtchn_upcall_pending = 1;
 }
 
 /*
index af8b55d661c8c57cc8a48d7a4d9119516ce480ea..a5f86c417b8928cc35a6002abc0d57599dc3dc9a 100644 (file)
@@ -669,6 +669,30 @@ int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip, int inst_l
     return inst_len;
 }
 
+static void hvm_send_assist_req(struct vcpu *v)
+{
+    ioreq_t *p;
+
+    p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
+    if ( unlikely(p->state != STATE_INVALID) ) {
+        /* This indicates a bug in the device model.  Crash the
+           domain. */
+        printf("Device model set bad IO state %d.\n", p->state);
+        domain_crash(v->domain);
+        return;
+    }
+    wmb();
+    p->state = STATE_IOREQ_READY;
+    notify_via_xen_event_channel(v->arch.hvm_vcpu.xen_port);
+}
+
+
+/* Wake up a vcpu whihc is waiting for interrupts to come in */
+void hvm_prod_vcpu(struct vcpu *v)
+{
+    vcpu_unblock(v);
+}
+
 void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
                   unsigned long count, int size, long value, int dir, int pvalid)
 {
@@ -682,13 +706,10 @@ void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
         domain_crash_synchronous();
     }
 
-    if (test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags)) {
-        printf("HVM I/O has not yet completed\n");
-        domain_crash_synchronous();
-    }
-    set_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags);
-
     p = &vio->vp_ioreq;
+    if ( p->state != STATE_INVALID )
+        printf("WARNING: send pio with something already pending (%d)?\n",
+               p->state);
     p->dir = dir;
     p->pdata_valid = pvalid;
 
@@ -714,10 +735,7 @@ void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
         return;
     }
 
-    p->state = STATE_IOREQ_READY;
-
-    evtchn_send(iopacket_port(v));
-    hvm_wait_io();
+    hvm_send_assist_req(v);
 }
 
 void send_mmio_req(
@@ -739,12 +757,9 @@ void send_mmio_req(
 
     p = &vio->vp_ioreq;
 
-    if (test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags)) {
-        printf("HVM I/O has not yet completed\n");
-        domain_crash_synchronous();
-    }
-
-    set_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags);
+    if ( p->state != STATE_INVALID )
+        printf("WARNING: send mmio with something already pending (%d)?\n",
+               p->state);
     p->dir = dir;
     p->pdata_valid = pvalid;
 
@@ -770,10 +785,7 @@ void send_mmio_req(
         return;
     }
 
-    p->state = STATE_IOREQ_READY;
-
-    evtchn_send(iopacket_port(v));
-    hvm_wait_io();
+    hvm_send_assist_req(v);
 }
 
 static void mmio_operands(int type, unsigned long gpa, struct instruction *inst,
index 56805dda267905259bf244b26c90a35ca7ab4cba..2059bff0eaf09382dd8c33c35eaf9efab00e9c66 100644 (file)
@@ -25,6 +25,7 @@
 #include <xen/sched.h>
 #include <xen/irq.h>
 #include <xen/softirq.h>
+#include <xen/hypercall.h>
 #include <asm/current.h>
 #include <asm/io.h>
 #include <asm/shadow.h>
@@ -2121,7 +2122,7 @@ static inline void svm_vmexit_do_hlt(struct vmcb_struct *vmcb)
         next_wakeup = next_pit;
     if ( next_wakeup != - 1 )
         set_timer(&current->arch.hvm_svm.hlt_timer, next_wakeup);
-    hvm_safe_block();
+    do_sched_op_compat(SCHEDOP_block, 0);
 }
 
 
index 8e3b5f07ffeefa9153018790dc15488193381022..7a644c351ab0781c80438aa0521ae4993c4cbea1 100644 (file)
@@ -370,18 +370,6 @@ void svm_do_launch(struct vcpu *v)
     if (v->vcpu_id == 0)
         hvm_setup_platform(v->domain);
 
-    if ( evtchn_bind_vcpu(iopacket_port(v), v->vcpu_id) < 0 )
-    {
-        printk("HVM domain bind port %d to vcpu %d failed!\n",
-               iopacket_port(v), v->vcpu_id);
-        domain_crash_synchronous();
-    }
-
-    HVM_DBG_LOG(DBG_LEVEL_1, "eport: %x", iopacket_port(v));
-
-    clear_bit(iopacket_port(v),
-              &v->domain->shared_info->evtchn_mask[0]);
-
     if (hvm_apic_support(v->domain))
         vlapic_init(v);
     init_timer(&v->arch.hvm_svm.hlt_timer,
@@ -439,10 +427,12 @@ void set_hsa_to_guest( struct arch_svm_struct *arch_svm )
 /* 
  * Resume the guest.
  */
+/* XXX svm_do_resume and vmx_do_resume are remarkably similar; could
+   they be unified? */
 void svm_do_resume(struct vcpu *v) 
 {
-    struct domain *d = v->domain;
-    struct periodic_time *pt = &d->arch.hvm_domain.pl_time.periodic_tm;
+    struct periodic_time *pt = &v->domain->arch.hvm_domain.pl_time.periodic_tm;
+    ioreq_t *p;
 
     svm_stts(v);
 
@@ -455,12 +445,16 @@ void svm_do_resume(struct vcpu *v)
         pickup_deactive_ticks(pt);
     }
 
-    if ( test_bit(iopacket_port(v), &d->shared_info->evtchn_pending[0]) ||
-         test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
-        hvm_wait_io();
-
-    /* We can't resume the guest if we're waiting on I/O */
-    ASSERT(!test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags));
+    p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
+    wait_on_xen_event_channel(v->arch.hvm.xen_port,
+                              p->state != STATE_IOREQ_READY &&
+                              p->state != STATE_IOREQ_INPROCESS);
+    if ( p->state == STATE_IORESP_READY )
+        hvm_io_assist(v);
+    if ( p->state != STATE_INVALID ) {
+        printf("Weird HVM iorequest state %d.\n", p->state);
+        domain_crash(v->domain);
+    }
 }
 
 void svm_launch_fail(unsigned long eflags)
index 4325b1443d3f392686faf9d0e334a4706e2ed3bc..cfd9fbbd55fb0460141c87e1401599759c02172c 100644 (file)
@@ -132,6 +132,9 @@ ENTRY(svm_asm_do_launch)
 ENTRY(svm_asm_do_resume)
 svm_test_all_events:
         GET_CURRENT(%ebx)
+        pushl %ebx
+        call svm_do_resume
+        addl $4, %esp
 /*test_all_events:*/
         xorl %ecx,%ecx
         notl %ecx
index 8396ffa5c770c0ee7cd301576dce816a30ba225b..b3746b529dd3ddb95e26ee991451e264c2cfb00d 100644 (file)
@@ -147,6 +147,8 @@ ENTRY(svm_asm_do_launch)
 ENTRY(svm_asm_do_resume)
 svm_test_all_events:
        GET_CURRENT(%rbx)
+        movq %rbx, %rdi
+        call svm_do_resume
 /*test_all_events:*/
         cli                             # tests must not race interrupts
 /*test_softirqs:*/
index 7ccfdb7aece5958d0167a34e4e08e4798281276c..02704f89c81c1028d14eb46f0da7bb3b1ceeed19 100644 (file)
@@ -232,7 +232,7 @@ static int vlapic_accept_irq(struct vcpu *v, int delivery_mode,
               "level trig mode for vector %d\n", vector);
             set_bit(vector, vlapic->regs + APIC_TMR);
         }
-        evtchn_set_pending(v, iopacket_port(v));
+        hvm_prod_vcpu(v);
 
         result = 1;
         break;
index def255b04ed61412d30b3f2a736c3e2e7615faa2..fee2c66bee7fc853dba0f4141c2424ea53bc5df3 100644 (file)
@@ -221,7 +221,7 @@ asmlinkage void vmx_intr_assist(void)
 
 void vmx_do_resume(struct vcpu *v)
 {
-    struct domain *d = v->domain;
+    ioreq_t *p;
     struct periodic_time *pt = &v->domain->arch.hvm_domain.pl_time.periodic_tm;
 
     vmx_stts();
@@ -235,12 +235,16 @@ void vmx_do_resume(struct vcpu *v)
         pickup_deactive_ticks(pt);
     }
 
-    if ( test_bit(iopacket_port(v), &d->shared_info->evtchn_pending[0]) ||
-         test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
-        hvm_wait_io();
-
-    /* We can't resume the guest if we're waiting on I/O */
-    ASSERT(!test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags));
+    p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
+    wait_on_xen_event_channel(v->arch.hvm.xen_port,
+                              p->state != STATE_IOREQ_READY &&
+                              p->state != STATE_IOREQ_INPROCESS);
+    if ( p->state == STATE_IORESP_READY )
+        hvm_io_assist(v);
+    if ( p->state != STATE_INVALID ) {
+        printf("Weird HVM iorequest state %d.\n", p->state);
+        domain_crash(v->domain);
+    }
 }
 
 /*
index 21f3daf554638fee21ea5506b8dac471a70e4b56..0a5b7fff726caaf73fc0c7e33a0870556e4be450 100644 (file)
@@ -245,18 +245,6 @@ static void vmx_do_launch(struct vcpu *v)
     if (v->vcpu_id == 0)
         hvm_setup_platform(v->domain);
 
-    if ( evtchn_bind_vcpu(iopacket_port(v), v->vcpu_id) < 0 )
-    {
-        printk("VMX domain bind port %d to vcpu %d failed!\n",
-               iopacket_port(v), v->vcpu_id);
-        domain_crash_synchronous();
-    }
-
-    HVM_DBG_LOG(DBG_LEVEL_1, "eport: %x", iopacket_port(v));
-
-    clear_bit(iopacket_port(v),
-              &v->domain->shared_info->evtchn_mask[0]);
-
     __asm__ __volatile__ ("mov %%cr0,%0" : "=r" (cr0) : );
 
     error |= __vmwrite(GUEST_CR0, cr0);
index 7084946cacd67caddb15698c3909080d26b5dbd9..0817c9b1ea4460b0f90be31a9a3df6a17cada866 100644 (file)
@@ -25,6 +25,7 @@
 #include <xen/irq.h>
 #include <xen/softirq.h>
 #include <xen/domain_page.h>
+#include <xen/hypercall.h>
 #include <asm/current.h>
 #include <asm/io.h>
 #include <asm/shadow.h>
@@ -141,6 +142,7 @@ static void vmx_relinquish_guest_resources(struct domain *d)
             free_domheap_page(VLAPIC(v)->regs_page);
             xfree(VLAPIC(v));
         }
+        hvm_release_assist_channel(v);
     }
 
     kill_timer(&d->arch.hvm_domain.pl_time.periodic_tm.timer);
@@ -2014,7 +2016,7 @@ void vmx_vmexit_do_hlt(void)
         next_wakeup = next_pit;
     if ( next_wakeup != - 1 ) 
         set_timer(&current->arch.hvm_vmx.hlt_timer, next_wakeup);
-    hvm_safe_block();
+    do_sched_op_compat(SCHEDOP_block, 0);
 }
 
 static inline void vmx_vmexit_do_extint(struct cpu_user_regs *regs)
index f78aea9dcfe60935ca08b6e697c3315a38a35b28..b4fea2fe7bd7ec6fc81bd5ac5fcee93c3ef69752 100644 (file)
@@ -94,6 +94,9 @@ vmx_process_softirqs:
         ALIGN
 ENTRY(vmx_asm_do_vmentry)
         GET_CURRENT(%ebx)
+        pushl %ebx
+        call vmx_do_resume
+        addl $4, %esp
         cli                             # tests must not race interrupts
 
         movl VCPU_processor(%ebx),%eax
index 767a4087af6d1810a9c79805da58db93cdf62b94..a3cffcf64a326ae80f184ce9e2e8aa817651ab77 100644 (file)
@@ -105,6 +105,8 @@ vmx_process_softirqs:
         ALIGN
 ENTRY(vmx_asm_do_vmentry)
         GET_CURRENT(%rbx)
+        movq %rbx, %rdi
+        call vmx_do_resume
         cli                             # tests must not race interrupts
 
         movl  VCPU_processor(%rbx),%eax
index 95b9696eb88a1e13b68d3f734c297901129ea9ea..567103aca4bfff69094b4452471113d29c97cd05 100644 (file)
@@ -77,6 +77,7 @@ hvm_disable(void)
         hvm_funcs.disable();
 }
 
+void hvm_create_event_channels(struct vcpu *v);
 void hvm_map_io_shared_page(struct vcpu *v);
 
 static inline int
@@ -85,8 +86,10 @@ hvm_initialize_guest_resources(struct vcpu *v)
     int ret = 1;
     if ( hvm_funcs.initialize_guest_resources )
         ret = hvm_funcs.initialize_guest_resources(v);
-    if ( ret == 1 )
+    if ( ret == 1 ) {
         hvm_map_io_shared_page(v);
+        hvm_create_event_channels(v);
+    }
     return ret;
 }
 
index 24fe2832b72de4b836edc719b91415dab3fb6140..646b5711deefb557690ce8ebee06dfa247998eb2 100644 (file)
@@ -150,13 +150,12 @@ static inline int irq_masked(unsigned long eflags)
 #endif
 
 extern void handle_mmio(unsigned long, unsigned long);
-extern void hvm_wait_io(void);
-extern void hvm_safe_block(void);
 extern void hvm_io_assist(struct vcpu *v);
 extern void pic_irq_request(void *data, int level);
 extern void hvm_pic_assist(struct vcpu *v);
 extern int cpu_get_interrupt(struct vcpu *v, int *type);
 extern int cpu_has_pending_irq(struct vcpu *v);
+extern void hvm_release_assist_channel(struct vcpu *v);
 
 // XXX - think about this, maybe use bit 30 of the mfn to signify an MMIO frame.
 #define mmio_space(gpa) (!VALID_MFN(get_mfn_from_gpfn((gpa) >> PAGE_SHIFT)))
index 9092254727ab90aa91df7e975fb34091e0b692e9..9d3440e5aa43e6f27bba3ff5bf9b996d51556b57 100644 (file)
@@ -44,11 +44,6 @@ static inline vcpu_iodata_t *get_vio(struct domain *d, unsigned long cpu)
     return &get_sp(d)->vcpu_iodata[cpu];
 }
 
-static inline int iopacket_port(struct vcpu *v)
-{
-    return get_vio(v->domain, v->vcpu_id)->vp_eport;
-}
-
 /* XXX these are really VMX specific */
 #define TYPE_MOV_TO_DR          (0 << 4)
 #define TYPE_MOV_FROM_DR        (1 << 4)
@@ -150,4 +145,6 @@ extern void hlt_timer_fn(void *data);
 
 void hvm_do_hypercall(struct cpu_user_regs *pregs);
 
+void hvm_prod_vcpu(struct vcpu *v);
+
 #endif /* __ASM_X86_HVM_SUPPORT_H__ */
index efd1f4c2bd14a0513ef6b8a9344f53e7ce75c2ea..f5e2249398fda92d7c5b5dd7be4eae97fee2891a 100644 (file)
@@ -38,6 +38,8 @@ struct hvm_vcpu {
     /* For AP startup */
     unsigned long       init_sipi_sipi_state;
 
+    int                 xen_port;
+
     /* Flags */
     int                 flag_dr_dirty;
 
index 7bc5782db90ffe6097f7d818173ec2df747fa04a..275f94df1163c75eaa9e194663c5c1c0dd6824eb 100644 (file)
@@ -69,7 +69,6 @@ struct vcpu_iodata {
     struct ioreq         vp_ioreq;
     /* Event channel port */
     unsigned int    vp_eport;   /* VMX vcpu uses this to notify DM */
-    unsigned int    dm_eport;   /* DM uses this to notify VMX vcpu */
 };
 typedef struct vcpu_iodata vcpu_iodata_t;
 
index 304466a945cbf9f423b0bd4e64485a9be60c1446..6817681e7dcecb4736e130c133ca8a5fec96c669 100644 (file)
@@ -12,6 +12,7 @@
 #include <xen/config.h>
 #include <xen/sched.h>
 #include <xen/smp.h>
+#include <xen/softirq.h>
 #include <asm/bitops.h>
 #include <asm/event.h>